home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 June
/
EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso
/
earcd
/
comm1
/
intsdkss.lha
/
examples
/
udp
/
udp_client.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-09
|
4KB
|
166 lines
/*
** UDP client program
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <proto/socket.h>
#define DEFAULT_PORT 54321
#define MAX_RETRIES 10
#define TIMEOUT_SECS 1
#define TERMINATOR "quit\n"
main ( argc, argv )
int argc;
char *argv[];
{
int s, retcode, done, retry, match, timeout;
long fromlen;
char recvbuffer[256], sendbuffer[256];
struct sockaddr_in addr, from;
struct servent * sp;
struct hostent * hp;
struct timeval timer;
fd_set rfds;
if ( argc != 2 ) {
fprintf ( stderr, "Usage:\t %s host \n", argv[0]);
exit (1);
}
/*
** Users may specify hosts in 2 different formats:
** hostnames or IP addresses (aka dotted quads).
** First try looking up the host as a hostname, and
** if that fails try as an IP address.
*/
memset(&addr, 0, sizeof(struct sockaddr_in) );
hp = gethostbyname( argv[1] );
if ( hp != NULL ) {
addr.sin_family = hp->h_addrtype ;
addr.sin_addr.s_addr = *((int *) hp ->h_addr);
} else {
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr( argv[1] );
if (addr.sin_addr.s_addr == -1) {
fprintf(stderr,"Can't lookup host %s\n",argv[1]);
exit(1);
}
}
/*
** Applications should get the service number from the services file.
** Try the services file first, and upon failure, use a default port
** number. This allows the example to run without modifying the
** system environment.
*/
sp = getservbyname( "example", "udp" );
if( sp != NULL ) {
addr.sin_port = sp->s_port;
} else {
addr.sin_port = DEFAULT_PORT;
}
/*
** Create a socket.
*/
s = socket ( AF_INET, SOCK_DGRAM, 0 );
if ( s == -1 ) {
perror("socket");
exit(1);
}
/*
** Client main loop - read data from stdin, send to server.
** Server echos back data, client reads data and prints on stdout.
** User may type quit or EOF to terminate program.
** Since data may get lost, the program must be prepared to
** deal with a lost message. This simple client uses select
** to wait for the incoming packet or a timeout. After a
** timeout it will retransmit the packet up to MAX_RETRIES
** times before giving up. If the program receives a packet
** that doesn't contain the expected data it is dropped.
*/
printf("Type a message, then type EOF character or quit to quit\n");
done = 0;
while (!done) { /* Main Client Loop */
if( fgets(sendbuffer, sizeof(sendbuffer), stdin) == NULL ){
if (feof(stdin)) {
strcpy(sendbuffer, "quit\n");
fprintf(stderr,"EOF - terminating server\n");
}
else {
perror("fgets");
exit(1);
}
}
if (!strncmp(sendbuffer, TERMINATOR, strlen(TERMINATOR))) {
done = 1;
}
retry = MAX_RETRIES+1;
match = 0;
while(!match && retry) { /* Transmit Loop */
retcode = sendto(s, sendbuffer, strlen(sendbuffer),
0, (struct sockaddr *)&addr, sizeof(addr));
if(retcode < 0 ) {
perror("sendto");
exit(1);
}
timeout = 0;
while(!match && !timeout) { /* Timeout Loop */
FD_ZERO(&rfds);
FD_SET(s, &rfds);
timer.tv_sec = TIMEOUT_SECS;
timer.tv_usec = 0;
retcode = select(s+1, &rfds, NULL, NULL, &timer);
if (retcode < 0) {
perror("select");
exit(1);
}
else if ( retcode == 0 ) { /* Timeout */
if (--retry) {
fprintf(stderr,"Client Timeout, retransmitting data\n");
timeout = 1;
}
else {
fprintf(stderr,"Client Timeout - giving up\n");
exit(1);
}
}
else { /* Get Packet */
fromlen = sizeof(from);
retcode = recvfrom(s, recvbuffer, sizeof(recvbuffer),
0, (struct sockaddr*)&from, &fromlen);
if ( retcode < 0 ){
perror("recvfrom");
exit(1);
}
recvbuffer[retcode] = 0;
fprintf(stdout,
"Response from %s, port %d, length %3d, data %s",
inet_ntoa(from.sin_addr),from.sin_port, retcode, recvbuffer);
if (!strcmp( sendbuffer, recvbuffer )) {/* Check Packet */
fputs(recvbuffer, stdout);
match=1;
}
}
}
}
}
exit(0);
}